package org.FaPe3D.core.cameras
{
	import fl.transitions.easing.*;
	
	import flash.events.Event;
	import flash.utils.Dictionary;
	
	import gs.*;
	
	import org.FaPe3D.Adapter;
	import org.FaPe3D.core.events.EventManager;
	import org.FaPe3D.engine.quality.Quality;
	import org.FaPe3D.engine.render.FPRender;
	import org.FaPe3D.utils.CameraPath;
	import org.FaPe3D.utils.PathList;
	import org.papervision3d.core.math.Number3D;
	
	public class Cameras extends EventManager
	{
		private var _dic:Dictionary = new Dictionary(true);
		private var _defaultCameraId:String = '';
		private var _animation:Boolean = false;
		
		public function Cameras()
		{
			
		}

		public function get cameras():Dictionary
		{
			return _dic;
		}
		
		public function setCameras(key:String, value:*, isDefault:Boolean = false):void
		{
			if(isDefault)
			{
				_defaultCameraId = key;
			}
			
			_dic[key] = value;
		}
		
		public function getCameras(key:String):*
		{
			return _dic[key];
		}
		
		public function getDefaultCamera():*
		{
			return getCameras(_defaultCameraId);
		}
		
		public function changeDefaultCamera(key:String):void
		{
			if(getCameras(key) != undefined)
			{
				_defaultCameraId = key;
			}else
			{
				trace('Error');
			}
		}
		
		public function moveByPath(key:String, path:PathList, startAt:Number = 0):void
		{
			if(!_animation)
			{
				_moveCamera(getCameras(key), path, startAt);
			}
		}
		
		public function moveCameraByPath(camera:*, path:PathList, startAt:Number = 0):void
		{
			if(!_animation)
			{
				_moveCamera(camera, path, startAt);
			}
		}
		
		public function magicalMoveCameraByPath(camera:*, path:Array, startAt:Number, speed:Array):void
		{
			if(!_animation)
			{
				_magicalMoveCamera(camera, path, startAt,speed);
			}
		}
		
		private function _moveCamera(camera:*, path:PathList, startAt:Number = 0):void
		{
			_animation = true;
			
			var cp:CameraPath = path.getByIndex(startAt);
			if(path.length > startAt+1)
			{
				Quality.FPQuality(true);
				//
				TweenMax.to(camera, cp.speed, {onComplete : _moveCamera, onCompleteParams:[camera, path, (startAt+1)] , overwrite: true, ease: None.easeInOut, x: checkValue(camera, cp.x, 'x') , y: checkValue(camera, cp.y, 'y'), z: checkValue(camera, cp.z, 'z') , rotationX : checkValue(camera, cp.rotationX, 'rotationX'), rotationY : checkValue(camera, cp.rotationY, 'rotationY'), rotationZ : checkValue(camera, cp.rotationZ, 'rotationZ')})
			}else
			{
				TweenMax.to(camera, cp.speed, {onComplete : function(){Quality.FPQuality(false); _animation=false; dispatchEvent(new Event( Event.COMPLETE ));} , overwrite: true, ease: None.easeInOut, x: checkValue(camera, cp.x, 'x'), y: checkValue(camera, cp.y, 'y'), z: checkValue(camera, cp.z, 'z') , rotationX : checkValue(camera, cp.rotationX, 'rotationX'), rotationY : checkValue(camera, cp.rotationY, 'rotationY'), rotationZ : checkValue(camera, cp.rotationZ, 'rotationZ')})
			}
			//
			if(Adapter.getCurrentAdapter().settings.setting['property.FPRender'])
			{
				FPRender.render( cp.speed );
			}
		}
		
		private function _magicalMoveCamera(camera:*, path:Array, startAt:Number = 0, speed:Array = null):void
		{
			_animation = true;
			
			var dataObj:Object = path[startAt];
			dataObj.onComplete = _magicalMoveCamera;
			dataObj.onCompleteParams = [camera, path, (startAt + 1), speed];
			Quality.FPQuality(true);
			if(path.length <= startAt+1)
			{
				dataObj.onComplete = function() {Quality.FPQuality(false); _animation = false; dispatchEvent(new Event( Event.COMPLETE )); };
				dataObj.onCompleteParams = null;
				dataObj.overwrite = true;
				//TweenMax.to(camera, cp.speed, {onComplete : function(){_animation=false; dispatchEvent(new Event( Event.COMPLETE ));} , overwrite: true, ease: None.easeInOut, x: checkValue(camera, cp.x, 'x'), y: checkValue(camera, cp.y, 'y'), z: checkValue(camera, cp.z, 'z') , rotationX : checkValue(camera, cp.rotationX, 'rotationX'), rotationY : checkValue(camera, cp.rotationY, 'rotationY'), rotationZ : checkValue(camera, cp.rotationZ, 'rotationZ')})
			}
			TweenMax.to(camera, speed[startAt], dataObj);
			//
			if(Adapter.getCurrentAdapter().settings.setting['property.FPRender'])
			{
				FPRender.render( speed[startAt] );
			}
			
		}
		
		private function checkValue(item:*, value:Number, name:String):Number
		{
			var i:Number = value;
			
			if(i+'' == 'null')
			{
				i = item[name]
			}
			
			return i;			
		}
		
		public function move(key:String, _to:Number3D, speed:Number):void
		{
			TweenMax.to(getCameras(key), speed, {ease: Bounce.easeOut, x: _to.x, y: _to.y, z: _to.z });
		}
		
	}
}